package com.mb.microservice.framework.exception;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.mb.microservice.framework.core.entity.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;

/**
 * @description: 全局处理异常
 * @author: Eibons
 * @create: 2020-10-29 13:50
 **/
@Component
@Slf4j
@RestControllerAdvice
@ControllerAdvice
public class GlobalExceptionHandler {
    
    
    /**
     * @param e :
     * @return : com.mb.microservices.fabric.exception.RestResult
     * @Description : 请求参数异常
     * @author Eibons
     * @date 2020/10/29 14:01
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public Result parameterMissingExceptionHandler(MissingServletRequestParameterException e) {
        log.error("", e);
        return Result.failed(ResultEnum.PARAMETER_ERROR.getCode(), "请求参数 " + e.getParameterName() + " 不能为空");
    }
    
    /**
     * @param e :
     * @return : com.mb.microservices.fabric.exception.RestResult
     * @Description : 请求参数异常
     * @author Eibons
     * @date 2020/10/29 14:00
     */
    @ExceptionHandler({HttpMessageNotReadableException.class})
    public Result parameterBodyMissingExceptionHandler(HttpMessageNotReadableException e) {
        log.error("", e);
        return Result.failed(ResultEnum.PARAMETER_ERROR.getCode(), "请传入正确请求体参数(RequestBody)");
    }
    
    /**
     * @param e :
     * @return : com.mb.microservices.fabric.exception.RestResult
     * @Description : 请求体参数异常（JSON格式异常）
     * @author Eibons
     * @date 2020/10/29 14:00
     */
    @ExceptionHandler(JsonProcessingException.class)
    public Result parameterBodyMissingExceptionHandler(JsonProcessingException e) {
        log.error("", e);
        return Result.failed(ResultEnum.PARAMETER_ERROR.getCode(), "请求参数非JSON标准格式");
    }
    
    
    /**
     * @param e :
     * @return : com.mb.microservices.fabric.exception.RestResult
     * @Description : 参数校验
     * @author Eibons
     * @date 2020/10/29 14:00
     */
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public Result methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        log.error("", e);
        BindingResult bindingResult = e.getBindingResult();
        StringBuffer sb = new StringBuffer();
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        for (int i = 0; i < fieldErrors.size(); i++) {
            sb.append(i + 1).append(":").append(fieldErrors.get(i).getDefaultMessage()).append(" | ");
        }
        return Result.failed(ResultEnum.PARAMETER_ERROR.getCode(), "请求参数错误: | " + sb.toString());
    }
    
    /**
     * @param e :
     * @return : com.mb.microservices.fabric.exception.RestResult
     * @Description : 其他异常
     * @author Eibons
     * @date 2020/10/29 14:00
     */
    @ExceptionHandler({Exception.class})
    public Result otherExceptionHandler(Exception e) {
        log.error("请求处理异常: ", e);
        // 判断异常中是否有错误信息，如果存在就使用异常中的消息，否则使用默认消息
        if (!StringUtils.isEmpty(e.getMessage())) {
            return Result.failed(ResultEnum.UNKNOWN_ERROR.getCode(), e.getMessage());
        }
        return Result.failed(ResultEnum.UNKNOWN_ERROR.getCode(), "未知异常");
    }
    
    
}
